%::PROVIDES=(
	name	=> ["STARTING_APP","REG_APP","DEREG_APP"],
	desc	=> [	"Change Application status to starting",
			"Register specified Application",
			"Deregister specified Application"],
	type	=> "request",
	code	=> \&::do_handle_startingapp
);

#########################################################################
# We also include DEREG_APP and REG_APP routines here...		#
#########################################################################

sub ::do_handle_startingapp {
my $args=shift;
my ($local_md5,$remote_md5,$app,$md5,$mfd);
my $cmdname=$args->{"_CMDNAME"};

	if(!exists($args->{APP})) {
		logwarn("$cmdname request missing APP argument");
		return "MISSING_ARG";
	}

	$app=$args->{APP};
	if($cmdname ne "REG_APP") {
		if(!exists($appmap->{$app})) {
			logwarn("Specified application is not registered");
			return "NOT_REGISTERED";
		}
	}

	if($cmdname eq "STARTING_APP") {
		if($appmap->{$app}->{STATE} eq "STARTING") {
			return "ALREADY_STARTING";
		}
		if($appmap->{$app}->{STATE} eq "STARTED") {
			return "ALREADY_STARTED";
		}

		#########################################################
		# Also need to check to see if this is a valid node	#
		# for this application and if not return the value	#
		# INVALID_NODE						#
		#########################################################

		my $x=hostname;
		if(!scalar(grep {/^$x$/} (split(/,/,$appmap->{$app}->{VALIDNODES})))) {
			return "INVALID_NODE";
		}

		$appmap->{$app}->{STATE}="STARTING";
		$appmap->{$app}->{STARTTIME}=time;
		$h=hostname;
		queue_it("APP_UPDATE app=$app state=STARTING node=$h starttime=".time);
		return "OK";
	}
	if($cmdname eq "DEREG_APP") {
		if($appmap->{$app}->{STATE} ne "DOWN") {
			return "NOT_STOPPED";
		}
		if(exists($args->{FORWARD})) {
			queue_it("$cmdname app=$app");
		}
		$appmap->{$app}=undef;
		delete $appmap->{$app};
		return "OK";
	} else {
		my ($r,$xx)=validate_application($app);
		if(!$r) {
			return "INVALID_CONF";
		}

		#################################################
		# MD5 the local file, and then ask for the 	#
		# details of the remote file...			#
		#################################################
		open($mfd,"/etc/cluster/$app/build.md5");
		$local_md5=<$mfd>;
		if(defined($local_md5)) {
			chomp $local_md5;
		}
		close($mfd);

		#################################################
		# Now send a request to the other server, 	#
		# to get the hex digest of its version.		#
		# Only if they agree is the application 	#
		# managed by the cluster.			#
		#################################################
		if(defined($cld_client) && defined($time_to_die)) {
			$remote_md5=$cld_client->send_msg(MSG => "CHECKSUM APP=$_");
			$cld_client->close_session;
			if(!defined($remote_md5)) {
				logwarn("Remote node not responding to CHECKSUM request!");
			}
			if(defined($remote_md5)) {
				if($remote_md5 eq "NO_SUCH_FILE") {
					logwarn("Remote node does not have application $_ build checksum!");
					$remote_md5=undef;
				}
				if($remote_md5 eq "NO_SUCH_APP") {
					logwarn("Remote node has no information about application $_!");
					$remote_md5=undef;
				}
				if($remote_md5 eq "INVALID_FILE") {
					logwarn("Remote node has no valid build checksum for application $_!");
					$remote_md5=undef;
				}
			}
		}
		#################################################################
		# When registering an application check to see if it is		#
		# already defined, and if so do nothing, otherwise add.		#
		#################################################################

		if(!defined($remote_md5) || $remote_md5 eq $local_md5) {
			if(!exists($appmap->{$app})) {
				$appmap->{$app}={};
				$appmap->{$app}->{STATE}="DOWN";
				$appmap->{$app}->{NODE}="";
				$appmap->{$app}->{MONITOR}=0;
				$appmap->{$app}->{STARTTIME}=0;
				$appmap->{$app}->{XMLINFO}=$xx;
				$appmap->{$app}->{VALIDNODES}=hostname.",$OTHER_NODE_NAME";
				if(defined($cld_client)) {
					$remote_md5=$cld_client->send_msg(MSG => "APP_UPDATE APP=$app STATE=DOWN NODE=. MONITOR=. STARTTIME=0 PROBE=yes");
					$cld_client->close_session;
				}
				logmsg("Application $app has been registered with the cluster daemons");
			} else {
				logmsg("Application $app already registered with cluster daemons.");
			}
		}
	}
	return "OK";
}

1;

